#pragma once

namespace AVUI {

class VisualTreeUtils
{
public:

    static void AsNonNullVisual(DependencyObject* pElement, Visual** ppVisual, Visual3D** ppVisual3D) 
    {
        *ppVisual = object_cast<Visual>(pElement);
        *ppVisual3D = object_cast<Visual3D>(pElement);
    }

    static bool AsVisualInternal(DependencyObject* pElement, Visual** ppVisual, Visual3D** ppVisual3D)
    {
        *ppVisual = object_cast<Visual>(pElement);
        *ppVisual3D = object_cast<Visual3D>(pElement);
        return true;
    }
    static void EnsureVisual(DependencyObject* pElement) { EnsureVisual(pElement, true); }
    static void EnsureVisual(DependencyObject* pElement, bool allowNull) 
    { 
        if(pElement == NULL)
        {
            if(!allowNull)
            {
                LibraryCriticalError();
            }
        }
        else
        {
            if (!is_type<Visual>(pElement) && !is_type<Visual3D>(pElement))
            {
                LibraryCriticalError();
            }
            pElement->VerifyAccess();
        }
    }

    static void SetFlagsToRoot(DependencyObject* pElement, bool value, VisualFlags::Enum flags)
    {
        Visual3D* pVisuald;
        Visual* pVisual;
        AsVisualInternal(pElement, &pVisual, &pVisuald);
        if (pVisual != NULL)
        {
            pVisual->SetFlagsToRoot(value, flags);
        }
        else if (pVisuald != NULL)
        {
            pVisuald->SetFlagsToRoot(value, flags);
        }
    }

    static DependencyObject* FindFirstAncestorWithFlagsAnd(DependencyObject* pElement, VisualFlags::Enum flags)
    {
        Visual3D* pVisuald;
        Visual* pVisual;
        AsVisualInternal(pElement, &pVisual, &pVisuald);
        if (pVisual != NULL)
        {
            return pVisual->FindFirstAncestorWithFlagsAnd(flags);
        }
        if (pVisuald != NULL)
        {
            return pVisuald->FindFirstAncestorWithFlagsAnd(flags);
        }
        return NULL;
    }

 
 


};
 
}; // namespace AVUI


